/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package Control;

import Control.exceptions.IllegalOrphanException;
import Control.exceptions.NonexistentEntityException;
import Control.exceptions.PreexistingEntityException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import Entidades.TipoHabitacion;
import Entidades.Reserva;
import java.util.ArrayList;
import java.util.List;
import Entidades.Estadia;
import Entidades.FueraServicio;
import Entidades.Habitacion;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 *
 * @author USUARIO
 */
public class HabitacionJpaController implements Serializable {

    public HabitacionJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Habitacion habitacion) throws PreexistingEntityException, Exception {
        if (habitacion.getReservaList() == null) {
            habitacion.setReservaList(new ArrayList<Reserva>());
        }
        if (habitacion.getEstadiaList() == null) {
            habitacion.setEstadiaList(new ArrayList<Estadia>());
        }
        if (habitacion.getFueraServicioList() == null) {
            habitacion.setFueraServicioList(new ArrayList<FueraServicio>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            TipoHabitacion tipo = habitacion.getTipo();
            if (tipo != null) {
                tipo = em.getReference(tipo.getClass(), tipo.getIdTipo());
                habitacion.setTipo(tipo);
            }
            List<Reserva> attachedReservaList = new ArrayList<Reserva>();
            for (Reserva reservaListReservaToAttach : habitacion.getReservaList()) {
                reservaListReservaToAttach = em.getReference(reservaListReservaToAttach.getClass(), reservaListReservaToAttach.getIdReserva());
                attachedReservaList.add(reservaListReservaToAttach);
            }
            habitacion.setReservaList(attachedReservaList);
            List<Estadia> attachedEstadiaList = new ArrayList<Estadia>();
            for (Estadia estadiaListEstadiaToAttach : habitacion.getEstadiaList()) {
                estadiaListEstadiaToAttach = em.getReference(estadiaListEstadiaToAttach.getClass(), estadiaListEstadiaToAttach.getIdEstadia());
                attachedEstadiaList.add(estadiaListEstadiaToAttach);
            }
            habitacion.setEstadiaList(attachedEstadiaList);
            List<FueraServicio> attachedFueraServicioList = new ArrayList<FueraServicio>();
            for (FueraServicio fueraServicioListFueraServicioToAttach : habitacion.getFueraServicioList()) {
                fueraServicioListFueraServicioToAttach = em.getReference(fueraServicioListFueraServicioToAttach.getClass(), fueraServicioListFueraServicioToAttach.getFueraServicioPK());
                attachedFueraServicioList.add(fueraServicioListFueraServicioToAttach);
            }
            habitacion.setFueraServicioList(attachedFueraServicioList);
            em.persist(habitacion);
            if (tipo != null) {
                tipo.getHabitacionList().add(habitacion);
                tipo = em.merge(tipo);
            }
            for (Reserva reservaListReserva : habitacion.getReservaList()) {
                Habitacion oldHabitacionOfReservaListReserva = reservaListReserva.getHabitacion();
                reservaListReserva.setHabitacion(habitacion);
                reservaListReserva = em.merge(reservaListReserva);
                if (oldHabitacionOfReservaListReserva != null) {
                    oldHabitacionOfReservaListReserva.getReservaList().remove(reservaListReserva);
                    oldHabitacionOfReservaListReserva = em.merge(oldHabitacionOfReservaListReserva);
                }
            }
            for (Estadia estadiaListEstadia : habitacion.getEstadiaList()) {
                Habitacion oldHabitacionOfEstadiaListEstadia = estadiaListEstadia.getHabitacion();
                estadiaListEstadia.setHabitacion(habitacion);
                estadiaListEstadia = em.merge(estadiaListEstadia);
                if (oldHabitacionOfEstadiaListEstadia != null) {
                    oldHabitacionOfEstadiaListEstadia.getEstadiaList().remove(estadiaListEstadia);
                    oldHabitacionOfEstadiaListEstadia = em.merge(oldHabitacionOfEstadiaListEstadia);
                }
            }
            for (FueraServicio fueraServicioListFueraServicio : habitacion.getFueraServicioList()) {
                Habitacion oldHabitacionOfFueraServicioListFueraServicio = fueraServicioListFueraServicio.getHabitacion();
                fueraServicioListFueraServicio.setHabitacion(habitacion);
                fueraServicioListFueraServicio = em.merge(fueraServicioListFueraServicio);
                if (oldHabitacionOfFueraServicioListFueraServicio != null) {
                    oldHabitacionOfFueraServicioListFueraServicio.getFueraServicioList().remove(fueraServicioListFueraServicio);
                    oldHabitacionOfFueraServicioListFueraServicio = em.merge(oldHabitacionOfFueraServicioListFueraServicio);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findHabitacion(habitacion.getNumero()) != null) {
                throw new PreexistingEntityException("Habitacion " + habitacion + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Habitacion habitacion) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Habitacion persistentHabitacion = em.find(Habitacion.class, habitacion.getNumero());
            TipoHabitacion tipoOld = persistentHabitacion.getTipo();
            TipoHabitacion tipoNew = habitacion.getTipo();
            List<Reserva> reservaListOld = persistentHabitacion.getReservaList();
            List<Reserva> reservaListNew = habitacion.getReservaList();
            List<Estadia> estadiaListOld = persistentHabitacion.getEstadiaList();
            List<Estadia> estadiaListNew = habitacion.getEstadiaList();
            List<FueraServicio> fueraServicioListOld = persistentHabitacion.getFueraServicioList();
            List<FueraServicio> fueraServicioListNew = habitacion.getFueraServicioList();
            List<String> illegalOrphanMessages = null;
            for (Estadia estadiaListOldEstadia : estadiaListOld) {
                if (!estadiaListNew.contains(estadiaListOldEstadia)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Estadia " + estadiaListOldEstadia + " since its habitacion field is not nullable.");
                }
            }
            for (FueraServicio fueraServicioListOldFueraServicio : fueraServicioListOld) {
                if (!fueraServicioListNew.contains(fueraServicioListOldFueraServicio)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain FueraServicio " + fueraServicioListOldFueraServicio + " since its habitacion field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (tipoNew != null) {
                tipoNew = em.getReference(tipoNew.getClass(), tipoNew.getIdTipo());
                habitacion.setTipo(tipoNew);
            }
            List<Reserva> attachedReservaListNew = new ArrayList<Reserva>();
            for (Reserva reservaListNewReservaToAttach : reservaListNew) {
                reservaListNewReservaToAttach = em.getReference(reservaListNewReservaToAttach.getClass(), reservaListNewReservaToAttach.getIdReserva());
                attachedReservaListNew.add(reservaListNewReservaToAttach);
            }
            reservaListNew = attachedReservaListNew;
            habitacion.setReservaList(reservaListNew);
            List<Estadia> attachedEstadiaListNew = new ArrayList<Estadia>();
            for (Estadia estadiaListNewEstadiaToAttach : estadiaListNew) {
                estadiaListNewEstadiaToAttach = em.getReference(estadiaListNewEstadiaToAttach.getClass(), estadiaListNewEstadiaToAttach.getIdEstadia());
                attachedEstadiaListNew.add(estadiaListNewEstadiaToAttach);
            }
            estadiaListNew = attachedEstadiaListNew;
            habitacion.setEstadiaList(estadiaListNew);
            List<FueraServicio> attachedFueraServicioListNew = new ArrayList<FueraServicio>();
            for (FueraServicio fueraServicioListNewFueraServicioToAttach : fueraServicioListNew) {
                fueraServicioListNewFueraServicioToAttach = em.getReference(fueraServicioListNewFueraServicioToAttach.getClass(), fueraServicioListNewFueraServicioToAttach.getFueraServicioPK());
                attachedFueraServicioListNew.add(fueraServicioListNewFueraServicioToAttach);
            }
            fueraServicioListNew = attachedFueraServicioListNew;
            habitacion.setFueraServicioList(fueraServicioListNew);
            habitacion = em.merge(habitacion);
            if (tipoOld != null && !tipoOld.equals(tipoNew)) {
                tipoOld.getHabitacionList().remove(habitacion);
                tipoOld = em.merge(tipoOld);
            }
            if (tipoNew != null && !tipoNew.equals(tipoOld)) {
                tipoNew.getHabitacionList().add(habitacion);
                tipoNew = em.merge(tipoNew);
            }
            for (Reserva reservaListOldReserva : reservaListOld) {
                if (!reservaListNew.contains(reservaListOldReserva)) {
                    reservaListOldReserva.setHabitacion(null);
                    reservaListOldReserva = em.merge(reservaListOldReserva);
                }
            }
            for (Reserva reservaListNewReserva : reservaListNew) {
                if (!reservaListOld.contains(reservaListNewReserva)) {
                    Habitacion oldHabitacionOfReservaListNewReserva = reservaListNewReserva.getHabitacion();
                    reservaListNewReserva.setHabitacion(habitacion);
                    reservaListNewReserva = em.merge(reservaListNewReserva);
                    if (oldHabitacionOfReservaListNewReserva != null && !oldHabitacionOfReservaListNewReserva.equals(habitacion)) {
                        oldHabitacionOfReservaListNewReserva.getReservaList().remove(reservaListNewReserva);
                        oldHabitacionOfReservaListNewReserva = em.merge(oldHabitacionOfReservaListNewReserva);
                    }
                }
            }
            for (Estadia estadiaListNewEstadia : estadiaListNew) {
                if (!estadiaListOld.contains(estadiaListNewEstadia)) {
                    Habitacion oldHabitacionOfEstadiaListNewEstadia = estadiaListNewEstadia.getHabitacion();
                    estadiaListNewEstadia.setHabitacion(habitacion);
                    estadiaListNewEstadia = em.merge(estadiaListNewEstadia);
                    if (oldHabitacionOfEstadiaListNewEstadia != null && !oldHabitacionOfEstadiaListNewEstadia.equals(habitacion)) {
                        oldHabitacionOfEstadiaListNewEstadia.getEstadiaList().remove(estadiaListNewEstadia);
                        oldHabitacionOfEstadiaListNewEstadia = em.merge(oldHabitacionOfEstadiaListNewEstadia);
                    }
                }
            }
            for (FueraServicio fueraServicioListNewFueraServicio : fueraServicioListNew) {
                if (!fueraServicioListOld.contains(fueraServicioListNewFueraServicio)) {
                    Habitacion oldHabitacionOfFueraServicioListNewFueraServicio = fueraServicioListNewFueraServicio.getHabitacion();
                    fueraServicioListNewFueraServicio.setHabitacion(habitacion);
                    fueraServicioListNewFueraServicio = em.merge(fueraServicioListNewFueraServicio);
                    if (oldHabitacionOfFueraServicioListNewFueraServicio != null && !oldHabitacionOfFueraServicioListNewFueraServicio.equals(habitacion)) {
                        oldHabitacionOfFueraServicioListNewFueraServicio.getFueraServicioList().remove(fueraServicioListNewFueraServicio);
                        oldHabitacionOfFueraServicioListNewFueraServicio = em.merge(oldHabitacionOfFueraServicioListNewFueraServicio);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = habitacion.getNumero();
                if (findHabitacion(id) == null) {
                    throw new NonexistentEntityException("The habitacion with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Habitacion habitacion;
            try {
                habitacion = em.getReference(Habitacion.class, id);
                habitacion.getNumero();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The habitacion with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<Estadia> estadiaListOrphanCheck = habitacion.getEstadiaList();
            for (Estadia estadiaListOrphanCheckEstadia : estadiaListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Habitacion (" + habitacion + ") cannot be destroyed since the Estadia " + estadiaListOrphanCheckEstadia + " in its estadiaList field has a non-nullable habitacion field.");
            }
            List<FueraServicio> fueraServicioListOrphanCheck = habitacion.getFueraServicioList();
            for (FueraServicio fueraServicioListOrphanCheckFueraServicio : fueraServicioListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Habitacion (" + habitacion + ") cannot be destroyed since the FueraServicio " + fueraServicioListOrphanCheckFueraServicio + " in its fueraServicioList field has a non-nullable habitacion field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            TipoHabitacion tipo = habitacion.getTipo();
            if (tipo != null) {
                tipo.getHabitacionList().remove(habitacion);
                tipo = em.merge(tipo);
            }
            List<Reserva> reservaList = habitacion.getReservaList();
            for (Reserva reservaListReserva : reservaList) {
                reservaListReserva.setHabitacion(null);
                reservaListReserva = em.merge(reservaListReserva);
            }
            em.remove(habitacion);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Habitacion> findHabitacionEntities() {
        return findHabitacionEntities(true, -1, -1);
    }

    public List<Habitacion> findHabitacionEntities(int maxResults, int firstResult) {
        return findHabitacionEntities(false, maxResults, firstResult);
    }

    private List<Habitacion> findHabitacionEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Habitacion.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Habitacion findHabitacion(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Habitacion.class, id);
        } finally {
            em.close();
        }
    }

    public int getHabitacionCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Habitacion> rt = cq.from(Habitacion.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
